package com.sip.stream.utils.zfy.encoder;

import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;

import com.sip.stream.utils.zfy.GSMediaSampleData;
import com.sip.stream.utils.zfy.consumer.IGSMediaObserver;
import com.sip.stream.utils.zfy.consumer.IGSVideoEncoderConsumer;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;

public abstract class AbstractVideoMediaCodecEncoder extends AbstractMediaCodecEncoder implements IGSVideoEncoder, GSMediaCodecAsyncCallBack.GSMediaCodecAsyncCallBackListener {
    private static final String TAG = "AbstractVideoMediaCodecEncoder";
    protected Handler backgroundHandler;
    protected HandlerThread backgroundThread;
    protected int bitRate;
    protected MediaCodec.BufferInfo cacheBufferInfo;
    protected ByteBuffer cacheConfigBuffer;
    protected GSMediaCodecAsyncCallBack codecAsyncCallBack;
    protected int frameInterval;
    private IGSMediaObserver<IGSNV12Consumer> observer;
    protected ArrayList<IGSVideoEncoderConsumer> listeners = new ArrayList<>();
    protected AtomicBoolean weakNetMode = new AtomicBoolean();
    private int addFrameCounter = 0;
    private int addFrameFilter = 0;
    private int addFrameCounter2 = 0;
    private int addFrameFilter2 = 0;
    private int addFrameCounter3 = 0;
    private int addFrameFilter3 = 0;
    private int performanceLevel = 0;

    @Override
    public void setForcedInterval(int i) {
    }

    protected abstract boolean setUpMediacodec(int width, int height, int bitrate, int frameRate, int frameInterval);

    @Override
    public void startEncode() {
    }

    public AbstractVideoMediaCodecEncoder(int width, int height, int bitrate, int frameRate, int frameInterval) {
        this.bitRate = bitrate;
        this.frameInterval = frameInterval;
        if (setUpMediacodec(width, height, bitrate, frameRate, frameInterval) && this.mediaCodec != null) {
            this.codecAsyncCallBack = new GSMediaCodecAsyncCallBack(this.mediaCodec, this, true);
            this.mediaCodec.setCallback(this.codecAsyncCallBack, getBackgroundHandler());
            this.mediaCodec.start();
        }
        Log.i(TAG, "frameRate " + frameRate);
    }

    public void changeBitRate(int videoBitrate) {
        Bundle bundle = new Bundle();
        bundle.putInt("video-bitrate", videoBitrate);
        this.mediaCodec.setParameters(bundle);
    }

    @Override
    protected void stopEncode() {
        Log.i(TAG, "stopEncode");
        this.isStop = true;
        GSMediaCodecAsyncCallBack gSMediaCodecAsyncCallBack = this.codecAsyncCallBack;
        if (gSMediaCodecAsyncCallBack != null) {
            gSMediaCodecAsyncCallBack.setStop(true);
            this.codecAsyncCallBack = null;
        }
        IGSMediaObserver<IGSNV12Consumer> iGSMediaObserver = this.observer;
        if (iGSMediaObserver != null) {
            iGSMediaObserver.onStop(this);
        }
    }

    @Override
    public void addObserver(IGSMediaObserver<IGSNV12Consumer> iGSMediaObserver) {
        this.observer = iGSMediaObserver;
    }

    @Override
    public void onNV12Stream(byte[] bArr, long j) {
        GSMediaCodecAsyncCallBack gSMediaCodecAsyncCallBack;
        if (this.isStop || (gSMediaCodecAsyncCallBack = this.codecAsyncCallBack) == null) {
            return;
        }
        gSMediaCodecAsyncCallBack.encode(bArr, j);
    }

    @Override
    public void addLisener(IGSVideoEncoderConsumer iGSVideoEncoderConsumer) {
        if (iGSVideoEncoderConsumer == null) {
            return;
        }
        this.listeners.add(iGSVideoEncoderConsumer);
        Log.i(TAG, "addLisener " + iGSVideoEncoderConsumer);
        if (this.cacheOutputFormate != null) {
            iGSVideoEncoderConsumer.setOutputFormat(this.cacheOutputFormate);
        }
        if (this.cacheConfigBuffer != null) {
            Log.i(TAG, "cacheConfigBuffer.remaining " + this.cacheConfigBuffer.remaining());
            ByteBuffer duplicate = this.cacheConfigBuffer.duplicate();
            Log.i(TAG, "cacheConfigBuffer.remaining " + this.cacheConfigBuffer.remaining() + " temp remaining: " + duplicate.remaining());
            iGSVideoEncoderConsumer.encodeVideoSuccess(GSMediaSampleData.createVideoSampleData(duplicate, this.cacheBufferInfo));
        }
        iGSVideoEncoderConsumer.addObserver(this);
    }

    @Override
    public void removeLisener(IGSVideoEncoderConsumer iGSVideoEncoderConsumer) {
        this.listeners.remove(iGSVideoEncoderConsumer);
        Log.i(TAG, "remove" + iGSVideoEncoderConsumer + "after removeLisener " + this.listeners.size());
        if (this.listeners.isEmpty()) {
            stopEncode();
        }
    }

    public void setOutputFormat() {
        this.cacheOutputFormate = this.mediaCodec.getOutputFormat();
        Iterator<IGSVideoEncoderConsumer> it = this.listeners.iterator();
        while (it.hasNext()) {
            it.next().setOutputFormat(this.cacheOutputFormate);
        }
    }

    protected synchronized Handler getBackgroundHandler() {
        if (this.backgroundThread == null || this.backgroundHandler == null) {
            HandlerThread handlerThread = new HandlerThread(TAG);
            this.backgroundThread = handlerThread;
            handlerThread.start();
            this.backgroundHandler = new Handler(this.backgroundThread.getLooper());
        }
        return this.backgroundHandler;
    }

    @Override
    public void encodeVideoSuccess(ByteBuffer byteBuffer, MediaCodec.BufferInfo bufferInfo) {
        try {
            Iterator<IGSVideoEncoderConsumer> it = this.listeners.iterator();
            while (it.hasNext()) {
                it.next().encodeVideoSuccess(GSMediaSampleData.createVideoSampleData(byteBuffer.duplicate(), bufferInfo));
            }
        } catch (Exception unused) {
        }
        if (bufferInfo.flags == 4) {
            this.listeners.clear();
            stopMediaCodec();
        } else if (bufferInfo.flags == 2) {
            this.cacheConfigBuffer = byteBuffer;
            this.cacheBufferInfo = bufferInfo;
        }
    }

    @Override
    public void setOutputFormat(MediaFormat mediaFormat) {
        this.cacheOutputFormate = mediaFormat;
        Iterator<IGSVideoEncoderConsumer> it = this.listeners.iterator();
        while (it.hasNext()) {
            it.next().setOutputFormat(this.cacheOutputFormate);
        }
    }

    @Override
    public void stopMediaCodec() {
        super.stopMediaCodec();
    }

    @Override
    public void setPerformanceLevel(int performanceLevel) {
        if (performanceLevel == this.performanceLevel) {
            return;
        }
        this.performanceLevel = performanceLevel;
        if (performanceLevel > 0) {
            Bundle bundle = new Bundle();
            bundle.putInt("video-bitrate", 819200);
            this.mediaCodec.setParameters(bundle);
            return;
        }
        Bundle bundle2 = new Bundle();
        bundle2.putInt("video-bitrate", this.bitRate);
        this.mediaCodec.setParameters(bundle2);
    }
}
